#include "ResourceScheduler.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "sys/IO.h"

static int comp(int * a, int * b){
   for(int i=0;i<MAX_RESOURCE_NUM; i++){
      if(a[i]<b[i]) return 0;
   }
   return 1;
}

static void add(int * a, int * b){
   for(int i=0;i<MAX_RESOURCE_NUM; i++){
      a[i]+=b[i];
   }
}


static int Bankertest(int Res,int pid){
   int remain[MAX_RESOURCE_NUM];
   for(int i=0;i<MAX_RESOURCE_NUM;i++){
      remain[i]=Remain[i];
   }
   remain[Res]--;
   jobs[pid].resource_remain[Res]--;

   int vis[MAX_JOB_N];
   memset(vis,0,sizeof(vis));
   int F=1; //F代表还有进程没有结束
   int E=1; //E代表下一轮循环还要执行，因为系统资源又增加了
   while(E){
      F=0;
      E=0;  //假定不执行了
      for(int i=0;i<MAX_JOB_N;i++){
         if(jobs[i].id==-1||vis[i]==1) continue;
         F=1;
         if(comp(remain,jobs[i].resource_remain)>0){
            add(remain,jobs[i].resource_requests);
            vis[i]=1;
            E=1;
         } 
      }    
   }

   if(F==1) {
      jobs[pid].resource_remain[Res]++;
      return 0;
   }
      
   return 1;
}

int applyResource(int pid, int Res, int t){
   if(Remain[Res]==0||Bankertest(Res,pid)==0){
      Log(pid,"fail to get resource and have gone to waiting queue",t,1);
      printf("Remain res is %d\n",Remain[Res]);
      q_push(&sleep[Res],pid,FCFS);
      jobs[pid].state=WAITING;
      return 0;
   }else{
      Log(pid,"get resource successively",t,1);
      Remain[Res]--;
      for(int i=0;i<rsc_num[Res];i++){
         if(sleep[Res].occupy[i]==-1){
            sleep[Res].occupy[i]=pid;
            return 1;
         }
      }
      LogErr("But a Invalid apply!",t);
      return 1;
   }
}

int releaseResources(int pid, int Res, int t){
   for(int i=0;i<rsc_num[Res];i++){
      if(sleep[Res].occupy[i]==pid){
         sleep[Res].occupy[i]=-1;
         jobs[pid].resource_requests[Res]--;
         Log(pid, "release resources",t,1);
         Remain[Res]++;
         if(q_empty(&sleep[Res])) return 1;  //无请求
         int id=q_front(&sleep[Res]);
         if(applyResource(id,Res,t)){
            q_push(&Ready,id,PSA);
            q_pop(&sleep[Res]);
            jobs[id].state=READY;
            return 1;                        //有请求，被接受
         }
         
         return 1;                           //有请求，被拒绝
      }
   }
   printf("Invalid resource release by process %d\n",pid);
   return 0;
}




